/**
 * Created by Peter Bortchagovsky.
 * 13.02.12 15:10
 */


if(jQuery) (function($){

//	var koache = {suggestions: {}, tree: {}, null_asked: false};
	var koache = {null_tree: []};

	$.fn.koatuudo = function(options) {
		var $element = this;
		if ($element.length > 1) {
			$element.each(function() { $(this).koatuudo(options) });
			return;
		}

		/* functions */

		function on_select(title, id, $el) {
			title = options.onselect_title_modification(title);

			$self.find( '.' + options.suggestion_control_field_class ).html(title);

			$element.val(id);
			$self.find( '.' + options.suggestion_field_class ).val( title ).attr({title: title});

			if (options.path) get_path(id).then(init_path);

			if ($.isFunction(options.onselect)) options.onselect(title, id, $el);
		}

		function toggle_tree() {
			$self.find( '.' + options.tree_button_class ).toggleClass('active');
			$self.find( '.' + options.tree_holder_class ).toggle();
			$self.find( '.' + options.suggestion_field_class ).attr({disabled: $(this).is('.active')});
		}

		/* settings */

		options = $.extend({
			  cache: true

			, init: true
			, init_title_attribute: 'data-title'
			, init_tree: false
			, init_suggestion: true
			, init_path: true
			, $init_element: $('<span>', {"class": 'init_loader', html: $('<img>', {src: '/img/ajax_loader_light.gif'}).after('Loading...')})
			, oninit: function(title, id, $el) {
				return true
			  }
			, path: true

			, onselect: function(title, id, $el) {
				return true
			  }
			, onselect_title_modification: function(title) {
				return title.replace(/<.+>/g, '').replace(/^\s*/, '').replace(/\s*$/, '');
			  }

			, api: 'get-koatuu'
			, suggestion_param: 'q'
			, tree_param: 'id'
			, init_param: 'init'
			, path_param: 'parent'

			, id_suffix: '_kodu'
			, wrapper_class: 'kodu'
			, tree_holder_class: 'tree_holder'
			, suggestion_field_class: 'suggestion_field'
			, tree_button_class: 'tree_button'
			, suggestion_control_field_class: 'suggestion_control_field'
			, path_class: 'path'
		}, options);

		/* init */

		var $self = $('<div>', {'class': options.wrapper_class, id: $(this).attr('id') + options.id_suffix});
		if (options.$init_element) $self.append(options.$init_element);
		$element.after($self);

		$element.addClass('kodu_master');
//		$element.css({marginTop: '-1.5em'});

		/* process functions */

		function init_tree(data) {
			$.jstree._themes = '/style/jsTree/';
			$self.find( '.' + options.tree_holder_class )
				.jstree({
					  plugins : [ "themes", "json_data", 'ui' ]
					, themes: { theme: 'classic' }
					, json_data: {
						  ajax: {
								url: function(n) {
									return ['/api', options.api, options.tree_param + '-' + (n.attr('id') || 'null'), '' ].join('/')
								}
						}
						, data: data
					  }
				})
				.on('click.jstree', function(event) {
						var $plus = $(event.target).prev();
						if ($plus.length && $plus[0].tagName == 'INS') $plus.click();
				})
				.on('dblclick.jstree', function(event) {
						var $li = $(event.target).parent();
						on_select($(event.target).text(), $li.attr('id'), $li);
						toggle_tree();
				})
//				.on('select_node.jstree', function(e, d) {
//						toggle_tree();
//						on_select($(d.rslt.e.target).text(), d.rslt.obj.attr('id'), d.rslt.obj);
//				})
				;
		}

		function init_suggestion(init_value) {

			$self.find( '.' + options.suggestion_field_class )
				.autocomplete({
//		    		  serviceUrl: ['/api', options.api, options.suggestion_param + '-'].join('/')
					  serviceUrl: '/api/' + options.api + '/'
					, minChars: 3
					, zIndex: 100
					, deferRequestBy: 100
					, suggestion_param: options.suggestion_param
//		    		, secondPartUrl: '/'
					, requestType: 'post'
					, value: init_value
					, url: function(q, ac) { return ac.serviceUrl }
					, clear: function(val) {
							if ($self.find( '.' + options.suggestion_control_field_class ).html() != $self.find( '.' + options.suggestion_field_class ).val()) {
								init_path([]);
								$element.each(function() { $(this).val('') });
							}
						}
					, onSelect: function(title, id) {
							on_select(title, id)
						}
					, valueModifier: function(value) {
							return value.replace(/<.+>/g, '').replace(/\s+$/, '')
						}
				})
				;
		}

		function init_path(data) {
			var $path = $self.find( '.' + options.path_class );
			data.pop();
			$path.html( $.map(data, function(obj) {return obj.name}).join( ', ' ) );
			$path[data.length ? 'show' : 'hide']();
		}

		function get_path(id) {
			return $
					.getJSON( ['/api', options.api, options.path_param + '-' + id, '' ].join('/') )
					.pipe(function(json) {
						path = json;
						return path;
					});
		}

		function get_null_tree() {
//			if (koache.null_tree.length) {
//				tree_init_data = koache.null_tree;
//			} else if (koache.null_tree.promise) {
//				return koache.null_tree;
//			} else {
//				koache.null_tree = $
				return $
						.getJSON( ['/api', options.api, options.tree_param + '-' + 'null', '' ].join('/') )
						.pipe(function(json, jqXHR) {
							tree_init_data = json;
							koache.null_tree = json;
							return tree_init_data;
						});
//				return koache.null_tree;
//			}
		}

		/* process */
		var tree_init_data = [], suggestion_init_title = '', path = [];

		// get init data or dietwice

		var def = $.Deferred();

		if (options.init) {

			var koatuu = $element.val() || 'null';
			if (options.init_suggestion && options.init_title_attribute) suggestion_init_title = $element.attr(options.init_title_attribute);

			if (!koatuu) {
				def = def.pipe( get_null_tree() );

			}   else {

				// how to pipe here?
				def = $
					.getJSON( ['/api', options.api, options.init_param + '-' + koatuu, '' ].join('/') )
					.pipe(function(json) {
							if (options.init_path) {
								if (json.path) path = json.path;
								else get_path(koatuu);
							}

							if (options.init_suggestion && json.name) suggestion_init_title = json.name;

							if (options.init_tree && json.tree) tree_init_data = json.tree;
							else return get_null_tree();
						})
					;
			}

		} else {
			def = get_null_tree();
		}


		def.then(function() {
			if (options.$init_element && options.$init_element instanceof jQuery) options.$init_element.hide();

			$('<p>', {'class': options.path_class})
				.appendTo($self)
				;

			// create component
			$('<input>', {type: 'text', 'class': options.suggestion_field_class})
				.appendTo($self)
				;

			$('<span>', {'class': options.suggestion_control_field_class})
				.appendTo($self)
				;

			$('<span>', {'class': options.tree_button_class})
				.appendTo($self)
				.click(toggle_tree)
				;

			$('<div>', {'class': options.tree_holder_class})
				.appendTo($self)
				;


			init_tree(tree_init_data);
			init_suggestion(suggestion_init_title);
			init_path(path);

			if (options.init) options.oninit(suggestion_init_title, $element.val(), $element);

		});


	};

})(jQuery);